/* Format object values */

#ifndef MC_ACCESSOR_FORMAT_HPP
#define MC_ACCESSOR_FORMAT_HPP

#include <ostream>

#include <memchart/type_traits.hpp>
#include <memchart/types.hpp>

namespace memchart
{
	template <bool IsObjectPointer, typename T>
	struct accessor_format_struct
	{
		accessor_format_struct (const T & val)
			: val(val)
		{ }

		const T & val;
	};


	/* Format an object value for output */
	template <bool IsObjectPointer, typename T>
	inline std::ostream & operator << (std::ostream & os,
		const accessor_format_struct<IsObjectPointer, T> & obj)
	{
		return os << obj.val;
	}

	/* Format an object pointer value for output */
	template <typename T>
	inline std::ostream & operator << (std::ostream & os,
		const accessor_format_struct<true, T> & obj)
	{
		if (!obj.val)
			return os << "NULL";
		else
			return os << to_string(reinterpret_cast<uintptr_t>(obj.val));
	}


	template <typename T>
	inline accessor_format_struct<is_object_pointer<T>::value, T>
		accessor_format (const T & val)
	{
		return accessor_format_struct<is_object_pointer<T>::value, T>(val);
	}
}

#endif /* MC_ACCESSOR_FORMAT_HPP */
